package predictionEngine;


import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class NominalSplit implements ISplit{
        private int attribute,position;
        private double[] values;
        private String[] realValues;
        private double strength;
        private String attributeName;
        
    public NominalSplit(Dataset dataset,int attribute) {
        this.attribute = attribute;
        attributeName=dataset.getAttribute(attribute).getName();
        findBestSplit(dataset);
        
    }
    
    public void findBestSplit(Dataset dataset) {
        List<double[]> instances = dataset.getInstances();        
        double sT = 0;
        int nrOfValues = dataset.getAttribute(attribute).nrOfAllowedValues();
        final int N=2,Y=1,VAL=0;
        ArrayList<double[]> B = new ArrayList<double[]>();
        for(int i = 0;i<nrOfValues;i++){
            double[] bPairs = new double[3];
            bPairs[VAL]=i;
            B.add(bPairs);
        }
        
        for(double[] instance:instances){
            int val = (int) instance[attribute];
            
            double y=instance[instance.length-1];
            B.get(val)[Y]+=y;
            B.get(val)[N]++;
            sT+=y;
        }
        Collections.sort(B,new ArrayComparer(Y));        
        
        for(double[] bPair:B)
            bPair[Y] = bPair[Y]/bPair[N];
        
        position =0 ;        
        strength = 0;
        
        int bestAttribute = 0;
        double sRight = sT, sLeft = 0;
        int nT = instances.size();
        int nRight = nT, nLeft = 0;
        for(int i =0;i < B.size()-1;i++){
            double[] bP = B.get(i);
            sLeft += bP[Y]; sRight -= bP[Y];
            nLeft += bP[N]; nRight -= bP[N];
            double newStrength = Math.pow(sLeft, 2)/nLeft+Math.pow(sRight, 2)/nRight;
            if(newStrength>strength){
                strength = newStrength;
                position = i;  
            }
        }
        
        values = new double[position+1];
        realValues = new String[values.length];
        for(int i = 0 ; i < values.length;i++){
            values[i]= B.get(i)[VAL];
            realValues[i]=dataset.getAttribute(attribute).getRealValue(values[i]);
        }
    }
    
    public String toString(){
        String s=realValues[0];
        for(int i = 1;i<realValues.length;i++)
            s+="|" + realValues[i];
        return attributeName + " = " + s;
    }

    public boolean test(double[] instance) {
        for(int i = 0;i<values.length;i++)
            if(values[i]==instance[attribute])
                return true;
        return false;
    }

    public double getStrength() {
        return strength;
    }

    public int getAttribute() {
        return attribute;
    }
}
